package com.az.miaoauth.service.impl;

import cn.hutool.core.lang.Validator;
import com.az.miaoapi.exception.BaseException;
import com.az.miaoapi.response.ResponseCode;
import com.az.miaoauth.domain.dto.EmailCodeDto;
import com.az.miaoauth.domain.dto.MessagePasswordDto;
import com.az.miaoauth.domain.po.TheUser;
import com.az.miaoauth.domain.vo.TokenVo;
import com.az.miaoauth.mapper.TheUserMapper;
import com.az.miaoauth.service.EmailService;
import com.az.miaoauth.service.LoginService;
import com.az.miaoauth.util.LoginUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.retry.annotation.Retryable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author baomidou
 * @since 2024-09-17
 */
@Service
@RequiredArgsConstructor
public class LoginServiceImpl extends ServiceImpl<TheUserMapper, TheUser> implements LoginService {

    private final TheUserMapper theUserMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final PasswordEncoder passwordEncoder;
    private final EmailService emailService;

    @Override
    @Retryable(noRetryFor = BaseException.class)
    public TokenVo loginByPassword(MessagePasswordDto messagePasswordDto) {
        String usermessage = messagePasswordDto.getUsermessage();
        String password = messagePasswordDto.getPassword();
        QueryWrapper<TheUser> queryWrapper = new QueryWrapper<>();
        if (Validator.isEmail(usermessage)) {
            queryWrapper.eq("email", usermessage);
        } else {
            queryWrapper.eq("username", usermessage);
        }
        TheUser user = Optional
                .ofNullable(theUserMapper.selectOne(queryWrapper))
                .orElseThrow(() -> new BaseException(ResponseCode.USER_NOT_EXIST));
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new BaseException(ResponseCode.LOGIN_FAILED);
        }
        return LoginUtil.login(user, redisTemplate);
    }

    @Override
    @Retryable(noRetryFor = BaseException.class)
    public TokenVo loginByEmail(EmailCodeDto emailCodeDto) {
        emailService.bindEmailCode(emailCodeDto);

        QueryWrapper<TheUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", emailCodeDto.getEmail());
        TheUser user = Optional
                .ofNullable(theUserMapper.selectOne(queryWrapper))
                .orElseThrow(() -> new BaseException(ResponseCode.USER_NOT_EXIST));

        return LoginUtil.login(user, redisTemplate);
    }


}
